package algorithm.leetcode.array;

import algorithm.leetcode.codeutils.ListNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @auther zhouliangliang
 * @date 2022/7/13 14:49
 * @description 螺旋赋值
 */
public class SpiralAssignment {
    private int rightBoundary;
    private int bottomBoundary;
    private int leftBoundary;
    private int topBoundary;
    private int lineIndex = 0;
    private int columnIndex = 0;

    public static void main(String[] args) {

        int[] array = new int[]{3,0,2,6,8,1,7,9,4,2,5,5,0};

        List<Integer> list = new ArrayList<>();
        Arrays.stream(array).forEach(item->{
            list.add(item);
        });
        ListNode node = ListNode.build(list);
        node.toString();

        new SpiralAssignment().spiralMatrix(3,5,node);
    }

    public int[][] spiralMatrix(int m, int n, ListNode head) {
        this.rightBoundary = n;
        this.bottomBoundary = m;
        this.leftBoundary = 0;
        this.topBoundary = 0;

        int[][] array = new int[m][n];
        String action = "moveRight";
        while( !(leftBoundary == rightBoundary || topBoundary == bottomBoundary)) {
            switch (action) {
                case "moveRight":
                    head = moveRight(array, lineIndex, columnIndex, rightBoundary, head);
                    action = nextAction("moveRight");
                    break;
                case "moveDown":
                    head = moveDown(array, lineIndex, columnIndex, bottomBoundary, head);
                    action = nextAction("moveDown");
                    break;
                case "moveLeft":
                    head = moveLeft(array, lineIndex, columnIndex, leftBoundary, head);
                    action = nextAction("moveLeft");
                    break;
                case "moveTop":
                    head = moveTop(array, lineIndex, columnIndex, topBoundary, head);
                    action = nextAction("moveTop");
                    break;
            }
        }

        for(int i=0; i<array.length; i++) {
            for(int j=0; j<array[0].length; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        return array;
    }

    private ListNode<Integer> moveRight(int[][]array, int i, int j, int rightBoundary, ListNode<Integer> head) {
        while (j < rightBoundary) {
            if(head == null) {
                array[i][j] = -1;
            } else {
                array[i][j] = head.getValue();
                head = head.getNext();
            }
            j = j+1;
        }
        lineIndex = i+1;
        columnIndex = j-1;
        topBoundary = topBoundary + 1;
        return head;
    }

    private ListNode<Integer> moveDown(int[][]array, int i, int j, int bottomBoundary, ListNode<Integer> head) {
        while (i < bottomBoundary) {
            if(head == null) {
                array[i][j] = -1;
            } else {
                array[i][j] = head.getValue();
                head = head.getNext();
            }
            i = i + 1;
        }
        lineIndex = i-1;
        columnIndex = j-1;
        rightBoundary = rightBoundary - 1;
        return head;
    }

    private ListNode<Integer> moveLeft(int[][]array, int i, int j, int leftBoundary, ListNode<Integer> head) {
        while (j >= leftBoundary) {
            if(head == null) {
                array[i][j] = -1;
            } else {
                array[i][j] = head.getValue();
                head = head.getNext();
            }
            j = j-1;
        }
        lineIndex = i - 1;
        columnIndex = j + 1;
        bottomBoundary = bottomBoundary - 1;
        return head;
    }

    private ListNode<Integer> moveTop(int[][] array, int i, int j, int topBoundary, ListNode<Integer> head) {
        while (i >= topBoundary) {
            if(head == null) {
                array[i][j] = -1;
            } else {
                array[i][j] = head.getValue();
                head = head.getNext();
            }
            i = i - 1;
        }
        lineIndex = i + 1;
        columnIndex = j + 1;
        leftBoundary = leftBoundary + 1;
        return head;
    }

    private String nextAction(String initAction) {
        if("moveRight".equals(initAction)) {
            return "moveDown";
        } else if("moveDown".equals(initAction)) {
            return "moveLeft";
        } else if("moveLeft".equals(initAction)) {
            return "moveTop";
        } else {
            return "moveRight";
        }
    }
}
